
package com.ideal.license.core.util;


import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.*;


/*****
 *  Linux

command

0、check CPUID：dmidecode -t processor | grep 'ID'

1、check server type sn：dmidecode | grep 'Product Name'

2、check mother board SN：dmidecode |grep 'Serial Number'

3、check system SN：dmidecode -s system-serial-number

4、check memmory info：dmidecode -t memory

5、check OEM info：dmidecode -t 11
 * 
 *
 */
 
public class HardWareUtils {
 
    /**
     * mother board 主板序列号.
     * 
     * @return
     */
    public static String getMotherboardSN() {
        String result = "";
        BufferedReader input = null;
        File file = null;

        try {
            file = File.createTempFile("realhowto", ".vbs");
            file.deleteOnExit();
            FileWriter  fw = new FileWriter(file);

            String vbs = "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
                    + "Set colItems = objWMIService.ExecQuery _ \n"
                    + "   (\"Select * from Win32_BaseBoard\") \n"
                    + "For Each objItem in colItems \n"
                    + "    Wscript.Echo objItem.SerialNumber \n"
                    + "    exit for  ' do the first cpu only! \n" + "Next \n";

            fw.write(vbs);
            fw.close();

            Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
            input = new BufferedReader(new InputStreamReader(p.getInputStream()));

            String line;
            while ((line = input.readLine()) != null) {
                result += line;
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
           doFinally(file, input);
        }

        return result.trim();
    }

    /**
     * HardDisk 序列号.
     *
     * @param drive
     *
     * @return
     */
    public static String getHardDiskSN(String drive) {
        String result = "";
        BufferedReader input = null;
        File file = null;
        try {
            file = File.createTempFile("realhowto", ".vbs");
            file.deleteOnExit();
            FileWriter fw = new FileWriter(file);

            String vbs = "Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\n"
                    + "Set colDrives = objFSO.Drives\n"
                    + "Set objDrive = colDrives.item(\""
                    + drive
                    + "\")\n"
                    + "Wscript.Echo objDrive.SerialNumber"; // see note

            fw.write(vbs);
            fw.close();

            Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
            input = new BufferedReader(new InputStreamReader(p.getInputStream()));

            String line;
            while ((line = input.readLine()) != null) {
                result += line;
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            doFinally(file, input);
        }

        return result.trim();
    }

    /**
     * CPU 序列号.
     *
     * @return
     */
    public static String getCPUSerial() {
        String result = "";
        File file = null;
        BufferedReader input = null;
        try {
            file = File.createTempFile("tmp", ".vbs");
            file.deleteOnExit();
            FileWriter fw = new FileWriter(file);
            String vbs = "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
                    + "Set colItems = objWMIService.ExecQuery _ \n"
                    + "   (\"Select * from Win32_Processor\") \n"
                    + "For Each objItem in colItems \n"
                    + "    Wscript.Echo objItem.ProcessorId \n"
                    + "    exit for  ' do the first cpu only! \n" + "Next \n";
 
            fw.write(vbs);
            fw.close();

            Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
            input = new BufferedReader(new InputStreamReader(p.getInputStream()));

            String line;
            while ((line = input.readLine()) != null) {
                result += line;
            }

        } catch (Exception e) {
            e.fillInStackTrace();
        } finally {
            doFinally(file, input);
        }

        if (StringUtils.isBlank(result)) {
            return null;
        }

        return result.trim();
    }

    /**
     * 获取mac list.
     * @return
     */
    public static List<String> getMacList() {
        List<String> list = new ArrayList<>();
        try {
            Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();

            for (NetworkInterface net : Collections.list(nets)) {
                byte[] mac = net.getHardwareAddress();
                StringBuilder sb = new StringBuilder();
                if (mac != null) {
                    for (int i = 0; i < mac.length; i++) {
                        sb.append(String.format("%02X%s", mac[i],(i < mac.length - 1) ? "-" : ""));
                    }

                    list.add(sb.toString());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return list;
    }

    /**
     * 获取ip地址.
     * @return
     */
    public static List<InetAddress> getIpList() {
        List<InetAddress> list = new ArrayList<>();

        try {
            for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) {
                NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
                for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {
                    InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
                    if (!inetAddr.isLoopbackAddress()) {// 排除loopback类型地址
                        if (inetAddr.isSiteLocalAddress()) {
                            // 如果是site-local地址，就是它了
                            list.add(inetAddr);
                        }
                    }
                }
            }
            if (!list.isEmpty()) {
                return list;
            }

            InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
            list.add(jdkSuppliedAddress);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return list;
    }

    private static void doFinally(File file, BufferedReader reader) {
        try {

            if (null != reader) {
                reader.close();
            }

            if (null != file) {
                file.delete();
            }

        } catch (Exception  e) {
            e.printStackTrace();
        }
    }

    /**
     * linux 主板序列号.
     * @return
     */
    public static String getMotherBoardSnLinux() {
        String cmd = "dmidecode -s baseboard-serial-number";
        List<String> cmds = initCmds(cmd);
        String result = cmd(cmds);

        if (StringUtils.isBlank(result)) {
            result = "Not Specified";
        }

        return result;
    }

    /**
     * 获取系统序列号.
     * @return
     */
    public static String getSystemSnLinux() {
        String cmd = "dmidecode -s system-serial-number";
        List<String> cmds = initCmds(cmd);
        String result = cmd(cmds);

        if (StringUtils.isBlank(result)) {
            result = "Not Specified";
        }

        return result;
    }

    /**
     * cpu序列号.
     * @return
     */
    public static List<String> getCpuListLinux() {
        String cmd = "dmidecode -t processor | grep 'Serial Number'|cut -b 17-";
        List<String> list = new ArrayList<>();
        List<String> cmds = initCmds(cmd);
        String cpu = cmd(cmds);

        if (StringUtils.isNotBlank(cpu)) {
            list = Arrays.asList(cpu.split(","));
        } else {
            list.add("Not Specified");
        }

        return list;
    }

    /**
     * 获取ip地址.
     * @return
     */
    public static List<String> getIpListLinux() {
        String cmd = "ifconfig | grep 'inet addr' | awk '{ print $2}'|cut -b 6- | grep -v 127.0.0.1";
        List<String> cmds = initCmds(cmd);
        List<String> list = new ArrayList<>();
        String ip = cmd(cmds);

        if (StringUtils.isNotBlank(ip)) {
            list = Arrays.asList(ip.split(","));
        } else {
            list.add("Not Specified");
        }

        return list;
    }

    /**
     * 获取mac地址.
     * @return
     */
    public static List<String> getMacListLinux() {
        String cmd = "ifconfig | grep 'HWaddr' | awk '{print $5}'";
        List<String> cmds = initCmds(cmd);
        List<String> list = new ArrayList<>();
        String mac = cmd(cmds);

        if (StringUtils.isNotBlank(mac)) {
            list = Arrays.asList(mac.split(","));
        } else {
            list.add("Not Specified");
        }

        return list;
    }

    /**
     * 获取硬盘sn.
     * @return
     */
    public static List<String> getDiskListLinux() {
        String cmd = "lsblk -o TYPE,NAME | grep -i disk | awk '{print $2}'";
        List<String> cmds = initCmds(cmd);
        List<String> list = new ArrayList<>();

        String disk = cmd(cmds);

        if (StringUtils.isNotBlank(disk)) {
            String[] disks = disk.split(",");

            for (String d : disks) {
                cmd = "smartctl --all /dev/" + d + " | grep 'Serial number'|awk '{print $3}'";
                cmds = initCmds(cmd);
                String diskSn = cmd(cmds);

                if (StringUtils.isNotBlank(diskSn)) {
                    list.add(diskSn);
                } else {
                    list.add("Not Specified");
                }
            }
        } else {
            list.add("Not Specified");
        }

        return list;
    }

    private static List<String> initCmds(String cmd) {
        List<String> cmds = new ArrayList<>();
        cmds.add("sh");
        cmds.add("-c");
        cmds.add(cmd);

        return cmds;
    }

    private static String cmd(List<String> cmds) {
        BufferedReader reader = null;
        StringBuffer result = new StringBuffer();

        try {
            ProcessBuilder pb = new ProcessBuilder(cmds);
            reader = new BufferedReader(new InputStreamReader(pb.start().getInputStream()));

            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line).append(",");
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            doFinally(null, reader);
        }

        if (StringUtils.isNotBlank(result.toString())) {
            return result.substring(0,result.length()-1);
        }

        return null;
    }
}